package br.com.esporte.repositorio.DAO.imp;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.stereotype.Repository;

import br.com.esporte.negocios.entidade.IEntidade;
import br.com.esporte.repositorio.DAO.IGenericDAO;
import br.com.esporte.repositorio.filtro.IFiltro;

/**
 * @author Milton Domingues
 */
@Repository
public abstract class HibernateGenericDAO<ENTIDADE extends IEntidade, ID extends Serializable, FILTRO extends IFiltro>
implements IGenericDAO<ENTIDADE, ID, FILTRO> {


	private Class<ENTIDADE> classe;

	@Autowired
	private SessionFactory sessionFactory;

	public HibernateGenericDAO(Class<ENTIDADE> classe) {
		this.classe = classe;
	}

	@Override
	public void alterar(ENTIDADE vo) {
		this.getSession().update(vo);
	}

	@Override
	@SuppressWarnings("unchecked")
	public ENTIDADE buscar(ID id) {
		return (ENTIDADE) this.getSession().get(this.classe, id);
	}

	@Override
	@SuppressWarnings("unchecked")
	public Collection<ENTIDADE> consultar(FILTRO filtro) {

		Query query = this.getSession().createQuery(filtro.getHql());
		filtro.setParametros(query);

		List<ENTIDADE> lista = null;
		if ((filtro.getInicio() != null) && (filtro.getQuantidade() != null)) {
			lista = query.setFirstResult(filtro.getInicio()).setMaxResults(filtro.getQuantidade()).list();
		} else {
			lista = query.list();
		}
		return lista;
	}

	public Query createQuery(String hql){
		return this.getSession().createQuery(hql);
	}

	public Session getSession() {
		return SessionFactoryUtils.getSession(this.sessionFactory, true);
	}

	public SessionFactory getSessionFactory() {
		return this.sessionFactory;
	}

	@Override
	public void inserir(ENTIDADE vo) {
		this.getSession().save(vo);
	}

	@Override
	@SuppressWarnings("unchecked")
	public ENTIDADE load(ID id) {
		return (ENTIDADE) this.getSession().load(this.classe, id);
	}

	@Override
	public void remover(ENTIDADE vo) {
		this.getSession().delete(vo);
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}
